package com.asdhawaii.otello.players;

import java.util.ArrayList;
import java.util.List;
import com.asdhawaii.otello.board.Move;
import com.asdhawaii.otello.board.Square;
import com.asdhawaii.otello.board.SquareContents;

/**
 * A mid-level AI that emphasizes playing stable moves.
 * 
 * The main benefit of playing a piece in a corner is that it is impossible to flip such a piece.
 * This provides a secure base from which to play.  This AI applies that logic to all other moves
 * that would be impossible for the opponent to flip, which are referred to as "stable moves."  
 * 
 * The Level4Ai will emphasize acquiring corners first, since that almost assures the AI of having
 * stable moves along the two walls connected at that corner.  If there are no corner moves
 * available, then this AI will attempt to play stable moves.  The AI will then apply the minima 
 * strategy to the results if found or to the original list of moves if no corners or stable moves 
 * were found.  
 * 
 * @author Branden Ogata
 *
 */

public class Level4Ai extends AbstractOtelloAi
{
  /**
   * Creates a new Level4Ai.
   * 
   * @param color The SquareContents indicating the color of the pieces for the new Level4Ai.
   * 
   */
  
  public Level4Ai(SquareContents color)
  {
    super(color);
  }

  @Override
  public Move getMove(Square[][] board, List<Move> moves)
  {
    List<Move> candidates = new ArrayList<Move>();
    
    candidates.addAll(AiStrategies.getCorners(board, moves, this.getColor()));
    
    // If no corners found, look for stable moves
    if (candidates.isEmpty())
    {
      candidates.addAll(AiStrategies.stableMoves(board, moves, this.getColor()));
    }
    
    // If no stable moves found, look for A square moves
    if (candidates.isEmpty())
    {
      candidates.addAll(AiStrategies.getASquares(board, moves, this.getColor()));
    }
    
    // If no A square moves found, avoid bad moves around corners
    if (candidates.isEmpty())
    {
      List<Move> cSquares = AiStrategies.getCSquares(board, moves, this.getColor());
      List<Move> xSquares = AiStrategies.getXSquares(board, moves, this.getColor());
      
      candidates.addAll(moves);
      candidates.removeAll(cSquares);
      candidates.removeAll(xSquares);
      
      // If no valid moves with that restriction, then prefer C over X squares
      if (candidates.isEmpty())
      {
        candidates.addAll(cSquares);
        
        if (candidates.isEmpty())
        {
          candidates.addAll(xSquares);
        }
      }
    }
    
    return AiStrategies.random(AiStrategies.minima(board, candidates, this.getColor()));
  }
}